package com.hibernate.lazyLoad;

import java.util.Set;

import javassist.bytecode.Opcode;

import org.hibernate.classic.Session;
import org.junit.Test;

import com.hibernate.domain.Classes;
import com.hibernate.domain.Student;
import com.hibernate.utils.HibernateUtils;

public class LazyLoadTest extends HibernateUtils {
	
	/**
	 * 类的延迟加载：
	 * 		当获取对象的属性的时候才发出sql语句
	 * 原理：
	 * 		代理模式：
	 * 			session.load()方法产生的是Classes的代理子类
	 * session.load和session.get方法的区别
	 * 		1、session.load方法使用延迟加载，session.get方法不使用延迟加载
	 * 		2、如果主键在数据库中没有对应的值,session.get方法返回Null值，不报错
	 * 								session.load方法，当调用对象的属性时，会报异常ObjectNotFoundException
	 * 		3、session.load方法有可能会导致no session异常，但是session.get方法不会
	 * 		4、<class name="com.hibernate.domain.Classes" table="classes" lazy="false">时，延迟加载不在起效
	 */
	@Test
	public void testClassLazyLoad() {
		Session session = sessionFactory.openSession() ;
		Classes classes = (Classes)session.load(Classes.class, 1L) ; //不发出sql语句
		System.out.println(classes.getCname());	//发出sql语句
		session.close() ;
	}
	
	/**
	 * 集合的延迟加载
	 * 		当遍历集合的时候发出sql语句
	 * 	<set name="students" cascade="all" inverse="false" lazy="true">
	 * 		lazy="false"	不支持延迟加载
	 * 		lazy="true"		支持延迟加载
	 * 		lazy="extra"	为更进一步的延迟加载，如果调用集合.size()方法时，只加载集合的个数，student信息不加载
	 */
	@Test
	public void testCollectionLazyLoad() {
		Session session = sessionFactory.openSession() ;
		Classes classes = (Classes)session.load(Classes.class, 1L) ; //没有发出sql语句
		Set<Student> students = classes.getStudents() ;
		for (Student student : students) {	//发出sql语句
			System.out.println(student);
		}
		session.close() ;
	}

}
